package Q_Learning;

public class Qtable {
	private double[][][] table;
	public static final int Xmax = GridWorld.xNum;
	public static final int Ymax = GridWorld.yNum;
	public static final int Actionmax = 4;
	public Qtable() {
		int i, j, a;
		table = new double[Xmax][Ymax][Actionmax];
		for ( i = 0 ; i < Xmax ; i++ ){
			for ( j = 0 ; j < Ymax ; j++ ){
				for ( a = 0 ; a < Actionmax ; a++ ){
					table[i][j][a] = 0;
				}
			}
		}
	}
	public Action getBestAction( int i, int j ){
		double max = Double.NEGATIVE_INFINITY, temp;
		int newx, newy;
		Action best = Action.UP;
		for ( Action a  : Action.values() ){
			temp = getQ(i,j,a.type);
			newx = i + a.xDis;
			newy = j + a.yDis;
			if (max <= temp && checkBoundary( newx, newy )){
				max = temp;
				best = a;
			}
			
		}
		return best;
	}
	public Action getRandAction( int i, int j ){
		Action rand;
		int newx = 0, newy = 0;
		int r;
		do{
			r = Math.round((float)Math.random()*Actionmax);
			switch(r){
			case 0:
				rand = Action.UP;
				break;
			case 1:
				rand = Action.RIGHT;
				break;
			case 2:
				rand = Action.DOWN;
				break;
			case 3:
				rand = Action.LEFT;
				break;
			default:
				rand = Action.LEFT;
				
			}
			
			newx = i + rand.xDis;
			newy = j + rand.yDis;
		}while(!checkBoundary( newx, newy ));
		return rand;
	}
	public boolean checkBoundary( int x, int y ) {
		return ( x < Xmax && y < Ymax && x >= 0 && y >= 0 );
	}
	public double getMaxQ( int i, int j ){
		return getQ( i, j, getBestAction(i, j).type );
	}
	public void setQ( int i, int j, int a, double value ) {
		table[i][j][a] = value;
	}
	public double getQ( int i, int j, int a ) {
		return table[i][j][a];//test svn
	}
	public void printQ(){
		GridPanel[][] grids = MainQLearning.inst.getGrids();
		String temp;
		for ( int i=0 ; i < Xmax ; i++ ){
			for ( int j=0 ; j < Ymax ; j++ ){
				for ( Action a : Action.values() ){
					temp = String.format( "%.6f", getQ(i,j,a.type));
					grids[i][j].direction[a.type].setText(temp);
					System.out.print(temp);
					System.out.print("\t");
				}
				System.out.print("\t");
			}
			System.out.println();
		}
	}
}
